package com.haoxin.ai_course.common.utils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;


/**
 * 日期时间类型的工具类
 */
public class DateUtil  {
	private static long MS_IN_DAY = 24 * 60 * 60 * 1000;
	public static String DATE_FORMATE= "yyyy-MM-dd";
	public static String TIME_FORMATE= "yyyy-MM-dd HH:mm:ss";
	public static String MM_DD= "MM.dd";
	
	/**
	 * 获取当前日期时间，包括年、月、日，也包括时、分、秒、毫秒。
	 * 
	 * @return
	 */
	public static Date currentDateTime() {
		return new Date();
	}

	public static String beforeOneHourToNowDate() {
		Calendar calendar = Calendar.getInstance();
		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 1);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH");
		return df.format(calendar.getTime());
	}

	public static String beforeOneDayToNowDate() {
		Calendar calendar = Calendar.getInstance();
		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		return df.format(calendar.getTime());
	}

	/**
	 * 获取当前日期，包括年、月、日（时、分、秒、毫秒均为0）。
	 * 
	 * @return
	 */
	public static Date currentDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 获得含有时间的id 字符串
	 * 
	 * @return
	 * 
	 */

	public static String getIdByTime() {

		Date now = new Date();

		SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmss");

		return simple.format(now);

	}

	/**
	 * 获取当前时间，包括时、分、秒、毫秒，日期为0001-01-01（无法用{@link Date}表示0000-00-00）。
	 * 
	 * @return
	 */
	public static Date currentTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis() % MS_IN_DAY);
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.YEAR, 1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		return calendar.getTime();
	}

	/**
	 * 将字符串表示的日期时间转化为{@link Date}。
	 *
	 * @param dateString 日期时间字符串。
	 * @param pattern    格式。
	 * @return dateString、pattern无效时返回null；转换过程发生异常时返回null，异常信息记录在日志中。
	 */
	public static Date parse(String dateString, String pattern) {
		if (StringUtils.isEmpty(dateString) || StringUtils.isEmpty(pattern))
			return null;
		try {
			SimpleDateFormat format = new SimpleDateFormat(pattern);
			return format.parse(dateString);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 将字符串表示的日期时间转化为{@link Date}。
	 *
	 * @param dateString 日期时间字符串。
	 * @param pattern    格式。
	 * @return dateString、pattern无效时返回null；转换过程发生异常时返回null，异常信息记录在日志中。
	 */
	public static Date parse(String dateString) {
		String pattern = "yyyyMMdd";
		if (StringUtils.isEmpty(dateString) || StringUtils.isEmpty(pattern))
			return null;
		try {
			SimpleDateFormat format = new SimpleDateFormat(pattern);
			return format.parse(dateString);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 对日期、时间进行加、减操作。
	 * 
	 * <pre>
	 * DateUtil.add(date, Calendar.YEAR, -1); // date减一年
	 * DateUtil.add(date, Calendar.HOUR, -4); // date减4个小时
	 * DateUtil.add(date, Calendar.MONTH, 3); // date加3个月
	 * </pre>
	 *
	 * @param date   日期时间。
	 * @param field  执行加减操作的属性，参考{@link Calendar#YEAR}、{@link Calendar#MONTH}、{@link Calendar#HOUR}等。
	 * @param amount 加减数量。
	 * @return 执行加减操作后的日期、时间。
	 */
	public static Date add(Date date, int field, int amount) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(date.getTime());
		calendar.add(field, amount);
		return calendar.getTime();
	}

	/**
	 * 去除时间（时分秒）部分，保留日期（年月日）部分。
	 *
	 * @param date 要操作的日期时间对象。
	 * @return 去除时间部分后的日期时间对象。
	 */
	public static Date truncateTime(Date date) {
		if (date == null)
			return null;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/**
	 * 去除日期（年月日）部分，保留时间（时分秒）部分。
	 *
	 * @param date 要操作的日期时间对象。
	 * @return 去除日期部分后的日期时间对象（返回的日期部分为0001-01-01，因为无法用{@link Date}表示0000-00-00）。
	 */
	public static Date truncateDate(Date date) {
		if (date == null)
			return null;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.YEAR, 1);
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.DAY_OF_MONTH, 0);
		return calendar.getTime();
	}

	public static String getMonthAndDayStr() {
		Calendar c = Calendar.getInstance();
		String monthStr = "";
		int month = c.get(Calendar.MONTH) + 1;
		if (month < 10) {
			monthStr = "0" + month;
		}
		int day = c.get(Calendar.DAY_OF_MONTH);
		return monthStr + day;

	}

	/**
	 * 返回日期为今天的指定天数、月数或天数之前的日期
	 *
	 * @param amount 0=当前日期，-1=之前日期，1=之后日期
	 * @return 日期字符串
	 *         <p>
	 *         chongfei add
	 * @fielde 减去的类型：6=天,2=月，1=年 超过的天数
	 */
	public static String getDateStrOfNumber(int field, int amount, String formatter) {
		Calendar cal = Calendar.getInstance();
		cal.add(field, amount);
		SimpleDateFormat sdf = new SimpleDateFormat(formatter);
		String nowtime = sdf.format(cal.getTime());
		return nowtime;
	}

	/**
	 * 将时间转换成时间戳
	 * 
	 * @param s 时间
	 * @return 时间戳
	 */
	public static Long dateToStamp(String s) {
		if (StringUtils.isEmpty(s)) {
			return null;
		}
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = simpleDateFormat.parse(s);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		long ts = date.getTime();
		long t = ts/1000;
		return t;
	}

	/**
	 * 获取昨日时间
	 * 
	 * @return
	 */
	public static String getYesterday() {
		Date date = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_YEAR, -1);
		date = calendar.getTime();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return format.format(date);
	}

	/**
	 * 返回 LocalDateTime实例 dt所在的 “年-月-日” 的时间戳
	 * 
	 * @param dt
	 * @return
	 */
	public static String getDate(LocalDateTime dt) {
		String ret = dt.toLocalDate().toString();
		return ret;
	}

	/**
	 * 返回当前时间偏移 days 天的时间戳
	 * 
	 * @param days 偏移天数
	 * @return
	 */
	public static LocalDateTime getShiftedDate(int days) {
		LocalDateTime ret = LocalDateTime.now().plusDays(days);
		return ret;
	}

	/**
	 * 返回当前时间偏移 days 天的0点时间戳
	 * 
	 * @param days 偏移天数
	 * @return
	 */
	public static LocalDateTime getShiftedStartDate(int days) {
		LocalDateTime ret = LocalDateTime.now().withHour(0).withMinute(0).withNano(0).withSecond(0).plusDays(days);
		return ret;
	}

	/**
	 * LocalDateTime 转成 Date
	 * 
	 * @param daytime
	 * @return
	 */
	public static Date localDateTimeToDate(LocalDateTime daytime) {

		Instant instant = daytime.atZone(ZoneId.systemDefault()).toInstant();
		return Date.from(instant);
	}

	/**
	 * 按格式返回时间
	 * 
	 * @return
	 */
	public static String getNowDate(String formatStr) {
		Date date = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		date = calendar.getTime();
		if (null == formatStr || "".equals(formatStr))
			formatStr = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		return format.format(date);
	}

	/**
	 * 按格式返回时间yyyy-MM-dd
	 *
	 * @return
	 */
	public static String getNowDate(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return format.format(date);
	}
	/**
	 * 按格式返回时间yyyy-MM-dd
	 *
	 * @return
	 */
	public static String getNowDate(Date date,String formatStr) {
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		return format.format(date);
	}

	/**
	 * 按格式返回时间MMdd
	 *
	 * @return
	 */
	public static String getNowDateMonth(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("MMdd");
		return format.format(date);
	}

	/**
	 * 按格式返回时间
	 *
	 * @return
	 */
	public static String parseDateTostring(Date date,String fromatStr ) {
		if(StringUtils.isBlank(fromatStr)) {
			fromatStr ="yyyyMMdd";
		}
		SimpleDateFormat format = new SimpleDateFormat(fromatStr);
		return format.format(date);
	}
	/**
	 * 日期字符串格式化成指定格式输出
	 * 
	 * @return
	 */
	public static String getFromatStrDate(String dateStr, String formatStr) {
		String dateResult = null;
//    	原始日期格式
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
//      格式化后的日期格式
		SimpleDateFormat format1 = new SimpleDateFormat(formatStr);
		Date d;
		try {
			d = format.parse(dateStr);
			dateResult = format1.format(d);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return dateResult;
	}

	/**
	 * 判断一年的第几周
	 * 
	 * @param datetime
	 * @return
	 * @throws java.text.ParseException
	 */
	public static Integer whatWeek(String datetime) throws java.text.ParseException {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		Date date = format.parse(datetime);
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		Integer weekNumbe = calendar.get(Calendar.WEEK_OF_YEAR);
		return weekNumbe;
	}

	public static void main(String[] args) {
//		System.out.println(getTimeUnitNumber("20200821", "20200823"));
//		List<String> scopeDayNumber = DateUtil.findTimeListByTimeArea("20190901", "20190902", UNIT_OF_TIME_WEEK);
//		List<String> scopeDayNumber1 = DateUtil.findTimeListByTimeArea("20200830", "20200831", UNIT_OF_TIME_WEEK);
////		int scopeDayNumber1 = DateUtil.nWeekBetweenTwoDate("20200901", "20200902");
////		List<String> scopeDayNumber = DateUtil.findMonth("20190120", "20210921");
////		List<String> contrastDayNumber = DateUtil.findQuarter("20190120", "20210120");
//		System.out.println(scopeDayNumber);
//		System.out.println(scopeDayNumber1);

		// 设置转换的日期格式
		long d = nDaysBetweenTwoDate("20211027", parseDateTostring(new Date(), "yyyyMMdd"));
		Double dd = (double)(d+1)/7;
		System.out.println(new BigDecimal(dd).setScale(2,BigDecimal.ROUND_HALF_UP));

	}

	public static String getDayOfTheWeek(int i){
		Calendar cal = Calendar.getInstance();
		int date = cal.get(Calendar.DAY_OF_MONTH);
		int n = cal.get(Calendar.DAY_OF_WEEK);
		if (n == 1) {
			n = 7;
		} else {
			n = n - 1;
		}
		// 日期格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		cal.set(Calendar.DAY_OF_MONTH, date + i - n);
		return sdf.format(cal.getTime());
	}

	public static long getDisTodayNumber(String startDay, String formatStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		long betweenDateNumber = 0;
		// 开始时间
		Date startDate;
		try {
			startDate = sdf.parse(startDay + "000000");
			// 得到相差的天数 betweenDate
			betweenDateNumber = (new Date().getTime() - startDate.getTime()) / (60 * 60 * 24 * 1000);
			return betweenDateNumber;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return betweenDateNumber;
	}

	/**
	 * 计算两个日期之间的天数，日期格式必须是yyyyMMdd，否则无法计算
	 * 
	 * @param firstString
	 * @param secondString
	 * @return
	 */
	public static long nDaysBetweenTwoDate(String firstString, String secondString) {
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
		Date firstDate = null;
		Date secondDate = null;
		try {
			firstDate = df.parse(firstString);
			secondDate = df.parse(secondString);
		} catch (Exception e) {
			// 日期型字符串格式错误
			System.out.println("日期型字符串格式错误");
		}
		return ((secondDate.getTime() - firstDate.getTime()) / (24 * 60 * 60 * 1000));
	}

	/**
	 * 计算两个日期之间的天数，日期格式必须是yyyyMMdd，否则无法计算
	 * 
	 * @param firstString
	 * @param secondString
	 * @return
	 */
	public static int nMonthBetweenTwoDate(String firstString, String secondString) {
		int result = 1;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		try {
			Calendar c1 = Calendar.getInstance();
			Calendar c2 = Calendar.getInstance();
			c1.setTime(sdf.parse(firstString));
			c2.setTime(sdf.parse(secondString));
			int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
			// 开始日期若小于结束日期
			if (year < 0) {
				year = -year;
				result = result + (year * 12 + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH));
			}
			result = result + (year * 12 + c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result + 1;
	}

	/**
	 * 计算两个日期之间的天数，日期格式必须是yyyyMMdd，否则无法计算
	 * 
	 * @param firstString
	 * @param secondString
	 * @return
	 */
	public static int nQuaterBetweenTwoDate(String fromDate, String toDate) {
		int quaterNumber = 1;
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
		try {
			Calendar cal = Calendar.getInstance();
			cal.setTime(df.parse(fromDate));
			Calendar cal1 = Calendar.getInstance();
			cal1.setTime(df.parse(toDate));
			while (cal1.getTime().after(cal.getTime())) {
				quaterNumber++;
				cal.add(Calendar.MONTH, 3);
			}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return quaterNumber;
	}

	

	public static int nWeekBetweenTwoDate(String fromDate, String toDate) {
		int weekNumber = 0;
		try {
			SimpleDateFormat dfyyyyMMdd = new SimpleDateFormat("yyyyMMdd");
			Calendar calS = Calendar.getInstance();

			calS.setTime(dfyyyyMMdd.parse(fromDate));

			Calendar calE = Calendar.getInstance();
			calE.setTime(dfyyyyMMdd.parse(toDate));
			int startNumber = calS.get( Calendar.WEEK_OF_YEAR)-1;
			while(calE.after(calS)||calE.equals(calS)) {
				calS.add(Calendar.DAY_OF_YEAR, 1);
				weekNumber = calS.get( Calendar.WEEK_OF_YEAR);
			}
			weekNumber  = weekNumber- startNumber;
		} catch (

		ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return weekNumber;
	}

	public static boolean isAfterToday(String dateStr) {
		boolean isAfter = false;
		SimpleDateFormat dfyyyyMMdd = new SimpleDateFormat("yyyyMMdd");
		try {
			Date paramDate = dfyyyyMMdd.parse(dateStr);
			Date nowDate = new Date();
			if (paramDate.after(nowDate)) {
				isAfter = true;
			}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return isAfter;
	}
	/**
	 * 
	 * @return
	 */
	public static int getDayOfWeek() {
		Calendar calendar = Calendar.getInstance();  
		Date date = new Date();  
		calendar.setTime(date);  
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)-1; 
		return dayOfWeek;
	}
/**
 *  根据输入构造时间
 * @param year 年 4位 
 * @param month 月 取值1-12
 * @param day  日 每月中的日期
 * @param hourOfDay 小时 0-24 
 * @param minute 分钟 0-59
 * @param second  秒 0-59
 * @return date 日期对象
 */
	
	public static Date buildDate(String dayStr,int hourOfDay,int minute,int second) {
		Calendar c=Calendar.getInstance();
		int year = Integer.parseInt(dayStr.substring(0,4));
		String monthStr = dayStr.substring(4,6);
		int month = Integer.parseInt(monthStr);
		int day =Integer.parseInt(dayStr.substring(6,8));
		c.set(year,month-1,day,hourOfDay,minute,second);
		return c.getTime();
	}
	 /**
     * 日期 格式化
     *
     * @param localDateTime /
     * @param patten /
     * @return /
     */
    public static String localDateTimeFormat(LocalDateTime localDateTime, String patten) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(patten);
        return df.format(localDateTime);
    }
}